﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace House_World
{
    class Dragon
    {
        Matrix world, view, projection;

        Model[] dragon;

        Texture2D tDragon;

        Effect effect;

        VertexPositionTexture[] verts;
        VertexBuffer vertexBuffer;
        short[] index;
        float[][] buffer;
        int size;
        Vector2[] ct;

        int currentFrame;
        float time;
        float speed;

        public Dragon(GameWindow Window, ContentManager Content, GraphicsDevice graphicsDevice)
        {
            this.world = Matrix.Identity;
            this.world*= Matrix.CreateTranslation(new Vector3(0,3.2f,-2));
            this.view = Matrix.CreateLookAt(new Vector3(0, 0, 2.5f),
                new Vector3(0, 1.5f, 0), Vector3.Up);

            this.projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                Window.ClientBounds.Width / (float)Window.ClientBounds.Height,
                0.1f, 1000);

            this.speed = 1;
            this.currentFrame = 0;
            this.time = 0;

            this.dragon = new Model[8];

            for (int i = 0; i < this.dragon.Length; i++)
                this.dragon[i] = Content.Load<Model>(@"Models\Dragon\" + (i + 1));

            this.tDragon = Content.Load<Texture2D>(@"Texture\dragon");

            this.effect = Content.Load<Effect>(@"Effect\Effect1");

            this.size = this.dragon[0].Meshes[0].MeshParts[0].VertexBuffer.VertexCount;
            this.buffer = new float[this.dragon.Length][];
            for (int i = 0; i < this.dragon.Length; i++)
            {
                this.buffer[i] = new float[this.size * 8];
                this.dragon[i].Meshes[0].MeshParts[0].VertexBuffer.GetData<float>(this.buffer[i]);
            }

            int idx = this.dragon[0].Meshes[0].MeshParts[0].IndexBuffer.IndexCount;
            this.index = new short[idx];
            this.dragon[0].Meshes[0].MeshParts[0].IndexBuffer.GetData<short>(index);

            this.verts = new VertexPositionTexture[this.size];
            this.vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionTexture),
                this.verts.Length, BufferUsage.None);
            this.vertexBuffer.SetData<VertexPositionTexture>(this.verts);

            this.ct = new Vector2[this.size];

            int k = this.currentFrame;
            int l = this.currentFrame + 1;

            if (l == this.dragon.Length)
                l = 0;

            for (int i = 0; i < this.size; i++)
            {
                int j = i * 8;

                Vector3 position = new Vector3(this.buffer[k][j], -this.buffer[k][j + 2], -this.buffer[k][j + 1]);

                this.ct[i] = new Vector2(this.buffer[0][j + 6], this.buffer[0][j + 7]);

                this.verts[i] = new VertexPositionTexture(position, this.ct[i]);
            }

        }
        public void Update(GameTime gameTime)
        {
            this.time += gameTime.ElapsedGameTime.Milliseconds * 0.001f * this.speed;

            if (this.time > 1)
            {
                this.time = 0;
                this.currentFrame++;
                if (this.currentFrame >= this.dragon.Length)
                    this.currentFrame = 0;
            }

            int k = this.currentFrame;
            int l = this.currentFrame + 1;

            if (l == this.dragon.Length)
                l = 0;

            for (int i = 0; i < this.size; i++)
            {
                int j = i * 8;

                Vector3 position = new Vector3(this.buffer[k][j],
                                              -this.buffer[k][j + 2],
                                              -this.buffer[k][j + 1]) * (1 - this.time) +
                                   new Vector3(this.buffer[l][j],
                                              -this.buffer[l][j + 2],
                                              -this.buffer[l][j + 1]) * this.time;

                this.verts[i] = new VertexPositionTexture(position, this.ct[i]);
            }


        }

        public void UnloadContent()
        {
            this.dragon = null;
            this.tDragon.Dispose();
            this.effect.Dispose();
        }
        public void Draw(GraphicsDevice graphicsDevice,Camera camera)
        {
            graphicsDevice.RasterizerState = RasterizerState.CullNone;

            graphicsDevice.SetVertexBuffer(this.vertexBuffer);

            this.effect.CurrentTechnique = this.effect.Techniques["Technique1"];
            this.effect.Parameters["Projection"].SetValue(camera.Projector);
            this.effect.Parameters["View"].SetValue(camera.View);
            this.effect.Parameters["World"].SetValue(this.world);
            this.effect.Parameters["colorTexture"].SetValue(this.tDragon);

            foreach (EffectPass pass in this.effect.CurrentTechnique.Passes)
            {
                pass.Apply();

                graphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList,
                    this.verts, 0, this.verts.Length, this.index, 0, this.index.Length / 3);
            }

        }
    }

}
